package m.html.util;

import m.html.element.Button;
import m.html.element.Element;
import m.html.element.Text;
import m.html.element.attr.ButtonType;
import m.html.element.other.DisplayItem;
import m.system.exception.MException;
import m.system.util.*;
import manage.util.DictionaryUtil;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

public class EchartsUtil {
    public static <T extends IVueListColumn> Element toPopoverContent(List<T> cols) {
        try {
            Element xElement=Element.tag("a-flex").A("wrap","wrap").A("gap","small");
            Element yElement=Element.tag("a-flex").A("wrap","wrap").A("gap","small");
            for (IVueListColumn col : cols) {
                if(col.getType().equals("index")) continue;
                if(col.isFalse()) continue;
                String gt=null!=col.getGroupTitle()&&col.getGroupTitle().length>0?"-"+ArrayUtil.connection(col.getGroupTitle(),","):"";
                if(StringUtil.isSpace(col.getNumberFormat())){
                    xElement.E(Element.tag("a-checkbox").A("value",col.getFieldAs()).E(new Text(col.getTitle())));
                }else{
                    yElement.E(Element.tag("a-checkbox").A("value",col.getFieldAs()).E(new Text(col.getTitle())));
                }
            }
            Element listElement = Element.tag("a-list").A("size", "small").A("style", "max-height:300px;overflow-y:auto;");
            listElement.E(
                Element.tag("a-list-item")
                .E(
                    Element.tag("a-list-item-meta")
                    .E(
                        Element.tag("template").A("#avatar")
                        .E(new Text("x轴"))
                    ),
                    Element.tag("div").A("style", "flex:5;")
                    .E(
                        Element.tag("a-checkbox-group")
                        .A("v-model:value", "searchParams['echarts_x']")
                        .E(xElement)
                    )
                ),
                Element.tag("a-list-item")
                .E(
                    Element.tag("a-list-item-meta")
                    .E(
                        Element.tag("template").A("#avatar")
                        .E(new Text("数据1"))
                    ),
                    Element.tag("div").A("style", "flex:5;")
                    .E(
                        Element.tag("a-checkbox-group")
                        .A("v-model:value", "searchParams['echarts_y1']")
                        .E(yElement)
                    )
                ),
                Element.tag("a-list-item")
                .E(
                    Element.tag("a-list-item-meta")
                    .E(
                        Element.tag("template").A("#avatar")
                            .E(new Text("数据2"))
                    ),
                    Element.tag("div").A("style", "flex:5;")
                    .E(
                        Element.tag("a-checkbox-group")
                        .A("v-model:value", "searchParams['echarts_y2']")
                        .E(yElement)
                    )
                )
            );
            return Element.tag("div").A("style", "width:400px;margin:-10px -10px 0;").E(
                listElement,
                Element.tag("div").A("style","padding-top:8px;text-align:center;border-top: 1px solid #8884;")
                .E(new Button(ButtonType.PRIMARY).A("size", "small").A("style", "width:130px;").E(new Text("查看")).setExtend(" @click=\"toEchartsPage();\" "))

            );
        }catch (Exception e){
            return Element.tag("div").E(new Text(e.getMessage()));
        }
    }
    public static <T extends IVueListColumn> JSONMessage toEchartsOption(String title, List<T> cols, List<?> list, Object[] ps, boolean simple) throws MException, ClassNotFoundException {
        String[] xfields=ps[0].toString().replaceAll("\\[","").replaceAll("\\]","").replaceAll("\"","").split(",");
        String[] y1fields=ps[1].toString().replaceAll("\\[","").replaceAll("\\]","").replaceAll("\"","").split(",");
        String[] y2fields=null!=ps[2]&&!"[]".equals(ps[2].toString())?ps[2].toString().replaceAll("\\[","").replaceAll("\\]","").replaceAll("\"","").split(","):new String[]{};
        List<JSONMessage> yAxisList= new ArrayList<>();
        yAxisList.add(new JSONMessage().push("type","value").push("splitLine",false));
        if(y2fields.length>0) yAxisList.add(new JSONMessage().push("type","value").push("position","right").push("splitLine",false));
        Map<String,List<DisplayItem>> disMap= new HashMap<>();
        Map<String,String> dfMap= new HashMap<>();
        Map<String,String> dtMap= new HashMap<>();
        for(String xf : xfields) {
            for (T col : cols) {
                if(col.getFieldAs().equals(xf)){
                    disMap.put(xf,col.getDisItems());
                    dfMap.put(xf,col.getDateFormat());
                    dtMap.put(xf,col.getDictType());
                }
            }
        }
        JSONMessage[] series=getSeries(y1fields,y2fields,cols);
        List<String> xAxisList= new ArrayList<>();
        for(Object data : list){
            StringBuilder txt= new StringBuilder();
            for(String xf : xfields){
                Object content= ActionUtil.getInAttribute(data, xf);
                String tmp;
                if(null==content){
                    tmp="";
                }else if(content instanceof Object[]){
                    tmp=ArrayUtil.connection((Object[])content,",");
                }else{
                    tmp=content.toString();
                }
                if(!StringUtil.isSpace(tmp)) {
                    if(!StringUtil.isSpace(dfMap.get(xf))) {
                        Date date;
                        if(content instanceof LocalDateTime){
                            Instant instant = ((LocalDateTime)content).toInstant(ZoneOffset.UTC);
                            date=Date.from(instant);
                        }else{
                            date=(Date)content;
                        }
                        txt.append(DateUtil.format(date, dfMap.get(xf)));
                    }else if(!StringUtil.isSpace(dtMap.get(xf))) {
                        txt.append(DictionaryUtil.getName(dtMap.get(xf), content));
                    }else{
                        StringBuilder tt=new StringBuilder();
                        List<DisplayItem> items=disMap.get(xf);
                        if(items.isEmpty()) tt.append(tmp);
                        else{
                            List<String> arr= new ArrayList<>();
                            if(content instanceof String[]) {
                                arr.addAll(Arrays.asList((String[]) content));
                            }else{
                                arr.add(tmp);
                            }
                            for(int n=0;n<arr.size();n++){
                                if(n>0) tt.append(",");
                                for(DisplayItem item : items) {
                                    if(StringUtil.noSpace(item.getValue()).equals(arr.get(n))) {
                                        tt.append(item.getTitle());
                                    }
                                }
                            }
                        }
                        txt.append(tt);
                    }
                }
            }
            if(!xAxisList.contains(txt.toString())){
                xAxisList.add(txt.toString());
            }
            int n=xAxisList.indexOf(txt.toString());
            for(int i=0;i<y1fields.length;i++){
                List<Double> ds= (List<Double>) series[i].get("data");
                Object content= ActionUtil.getInAttribute(data, y1fields[i]);
                String tmp=null==content?"":content.toString();
                double d=0D;
                if(!StringUtil.isSpace(tmp)) {
                    d=Double.parseDouble(tmp);
                }
                if(ds.size()<=n){
                    ds.add(NumberUtil.round(d));
                }else{
                    ds.set(n,NumberUtil.round(ds.get(n)+d,2));
                }
            }
            for(int i=0;i<y2fields.length;i++){
                List<Double> ds= (List<Double>) series[y1fields.length+i].get("data");
                Object content= ActionUtil.getInAttribute(data, y2fields[i]);
                String tmp=null==content?"":content.toString();
                double d=0D;
                if(!StringUtil.isSpace(tmp)) {
                    d=Double.parseDouble(tmp);
                }
                if(ds.size()<=n){
                    ds.add(NumberUtil.round(d));
                }else{
                    ds.set(n,NumberUtil.round(ds.get(n)+d));
                }
            }
        }
        List<String> legendList= new ArrayList<>();
        for(JSONMessage json : series){
            legendList.add(json.get(String.class,"name"));
        }
        JSONMessage xAxis=new JSONMessage().push("type","category").push("data",xAxisList);
        JSONMessage json=new JSONMessage();
        if(!simple){
            json.push("title",new JSONMessage().push("text",title).push("top","15px").push("left","15px"));
            json.push("dataZoom",new JSONMessage[]{new JSONMessage()});
            json.push("toolbox",new JSONMessage()
                .push("top","15px")
                .push("right","80px")
                .push("feature",new JSONMessage()
                    .push("magicType",new JSONMessage()
                        .push("type",new String[]{"line","bar","stack","tiled"})
                    )
                    .push("restore",new JSONMessage())
                    .push("saveAsImage",new JSONMessage())
                )
            );
            json.push("legend",new JSONMessage().push("data",legendList).push("top","15px"));
            json.push("grid",new JSONMessage()
                .push("top","90px")
                .push("left","15px")
                .push("right","15px")
                .push("bottom","55px")
                .push("containLabel",true)
            );
        }else{
            json.push("grid",new JSONMessage()
                .push("top","3px")
                .push("left","-15px")
                .push("right","-3px")
                .push("bottom","1px")
                .push("containLabel",true)
            );
            for(JSONMessage y : yAxisList){
                y.push("show",false);
            }
            xAxis.push("show",false);
        }
        json.push("yAxis",yAxisList.toArray(new JSONMessage[]{}));
        json.push("xAxis",xAxis);
        json.push("series",series);
        json.push("tooltip",new JSONMessage()
            .push("trigger","axis")
        );
        return json;
    }
    private static <T extends IVueListColumn> JSONMessage[] getSeries(String[] y1fields, String[] y2fields, List<T> cols){
        List<JSONMessage> jsons= new ArrayList<>();
        for(String y1f : y1fields){
            for(T col : cols){
                if(col.getFieldAs().equals(y1f)){
                    String gt=null!=col.getGroupTitle()&&col.getGroupTitle().length>0?("-"+ArrayUtil.connection(col.getGroupTitle(),",")):"";
                    jsons.add(new JSONMessage()
                        .push("name",col.getTitle()+gt)
                        .push("data",new ArrayList<Double>())
                        .push("type","line")
                    );
                }
            }
        }
        for(String y2f : y2fields){
            for(T col : cols){
                if(col.getFieldAs().equals(y2f)){
                    String gt=null!=col.getGroupTitle()&&col.getGroupTitle().length>0?("-"+ArrayUtil.connection(col.getGroupTitle(),",")):"";
                    jsons.add(new JSONMessage()
                        .push("name",col.getTitle()+gt)
                        .push("data",new ArrayList<Double>())
                        .push("type","bar")
                        .push("yAxisIndex",1)
                    );
                }
            }
        }
        return jsons.toArray(new JSONMessage[]{});
    }
}
